<?php

namespace Hilaoyu\LaravelExtend\Services\Assents\Controllers;

use Hilaoyu\LaravelExtend\ControllerBase;
use Hilaoyu\LaravelExtend\Services\Auth\AuthService;
use Hilaoyu\LaravelExtend\Supports\AuthorizeCheck;
use Hilaoyu\Utils\UtilStr;
use Illuminate\Http\Request;
use Illuminate\Routing\Route;
use Illuminate\Routing\Router;
use Illuminate\Support\Arr;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;
use Illuminate\Http\Response;


class ConfigController extends ControllerBase
{
    private  bool $authCheck = true;

    public function routeCheckApi(Request $request){
        $currentRouteName = \Route::currentRouteName();
        $route_connector = Str::before(Str::after($currentRouteName,'api.l-e-s.assents.'),'.');
        $config = config('assents.route_connectors.'.$route_connector,[]);
        $route_name = trim($request->route('name',$request->input("name","")));

        if(!$route_name || ! $route = \Route::getRoutes()->getByName($route_name)){
            return comResponse()->failed()->json();
        }

        if(!$this->checkRoute($route,$config)){
            if($this->authCheck === false){
                return response()->json(['message' => 'Unauthorized'], Response::HTTP_UNAUTHORIZED);
            }
            return comResponse()->failed()->json();
        }

        return comResponse()->success()->with($this->formatRouteReturn($route))->json();
    }

    public function routesApi(Request $request){
        $currentRouteName = \Route::currentRouteName();
        $route_connector = Str::before(Str::after($currentRouteName,'api.l-e-s.assents.'),'.');
        $routes = $this->getRoutes($route_connector);

        return comResponse()->success()->with($routes)->json();
    }
    public function servicesJs(Request $request){
        $currentRouteName = \Route::currentRouteName();
        $route_connector = Str::before(Str::after($currentRouteName,'web.l-e-s.assents.'),'.');

        $routes = $this->getRoutes($route_connector);
        $session_id = '';
        $session = $request->session();
        if($session){
            $session_id = $session->getId();
        }


        return comResponse()->success()
            ->with(md5($session_id),"routeCacheId")
            ->with($routes,'routes')
            ->with($route_connector,'route_connector')
            ->withHeader('Content-Type','application/javascript')
            ->view("LaravelExtend::assents.services");
    }

    protected function getRoutes($route_connector=''){
        $config_key = 'assents.route_connectors.'.$route_connector;
        $config = config($config_key,[]);
        if(!data_get($config,'use_global_services',false)){
            return [];
        }

        $domain = \request()->getSchemeAndHttpHost();
        $cache_key = 'laravel_extend_assents_routes_'.UtilStr::replace($route_connector,['\\.'=>'_']).'_'.config('app.env','').'_'.md5($domain).'_'.trim(AuthService::AuthenticatedUser('id'));
        //Cache::forget($cache_key);
        $routes = Cache::remember($cache_key,Carbon::now()->addMinutes(5),function () use ($config){

            return collect(\Route::getRoutes()->getRoutesByName())
                ->filter(function ($route, $route_name) use ($config){
                    return $this->checkRoute($route,$config,true);

                    /*//dump($route_name,$route->middleware());
                    if(in_array('assents_route_exclude',$route->middleware())){
                        return false;
                    }
                    if(!AuthorizeCheck::CheckRoute($route_name)){
                        //dump('AuthorizeCheck false');
                        return false;
                    }
                    //dump('AuthorizeCheck true');
                    //排除 ignition.开头的
                    if(Str::startsWith($route_name, 'ignition.')){
                        return false;
                    }
                    //排除 配置中的 exclude_name_prefix
                    if(Str::startsWith($route_name, data_get($config,'exclude_name_prefix',[]))){
                        return false;
                    }

                    //配置中 include_name_prefix ，如果为空则全部，不为空时只包含配置中的
                    $include_name_prefix = data_get($config,'include_name_prefix',[]);
                    if(empty($include_name_prefix) || Str::startsWith($route_name, $include_name_prefix)){
                        return true;
                    }*/

                    return false;
                    //return Str::startsWith($index, 'api.');// || Str::startsWith($index, 'files.');
                })
                ->map(function ($item) {
                    return $this->formatRouteReturn($item);
                });
        });


        return $routes;
    }

    protected function checkRoute(Route $route,$config,$checkIgnition = false){
        $route_name = $route->getName();
        //配置中 include_name_prefix ，如果为空则全部，不为空时只包含配置中的
        $include_name_prefix = data_get($config,'include_name_prefix',[]);
        if(!empty($include_name_prefix) && !Str::startsWith($route_name, $include_name_prefix)){
            return false;
        }

        if($checkIgnition){
            //排除 有中间件 assents_route_exclude 的
            if(in_array('assents_route_exclude',$route->gatherMiddleware())){
                return false;
            }
            //排除 ignition.开头的
            if(Str::startsWith($route_name, 'ignition.')){
                return false;
            }
        }

        //排除 配置中的 exclude_name_prefix
        if(Str::startsWith($route_name, data_get($config,'exclude_name_prefix',[]))){
            return false;
        }


        if(!AuthorizeCheck::CheckRoute($route_name)){
            //dump('AuthorizeCheck false');
            $this->authCheck = false;
            return false;
        }
        //dump('AuthorizeCheck true');

        return true;
    }

    protected function formatRouteReturn(Route $route)
    {
        $domain = \request()->getSchemeAndHttpHost();
        if (!$domain) {
            $domain = env('APP_URL', '');
        }
        return ['uri' => '/' . $route->uri(), 'method' => Arr::first($route->methods(), function ($value) {
            return $value != 'HEAD';
        })];
    }


}
